-------------------------------------------------------------------------------------
-- -*- coding: utf-8 -*-
--
-- @author:   ztw
-- @email:    986241885@qq.com
-- @date:     2024/7/2
-- @module:   exchange
-- @describe:
-- @version:  v1.0
--

-------------------------------------------------------------------------------------

---@class exchange
local exchange = {}
local this = exchange
local decider = decider
local exchange_unit = exchange_unit
local exchange_ctx = exchange_ctx
---@type redis
local redis = import("game/func/redis")
---@type item
local item = import("game/func/item")
local trace = trace
---@type api
local api = import("api/api")
---@type utils
local utils = import("base/utils")



------------------------------------------------------------------------------------------------------------------------
-- [读取] 获取交易行当前页面的物品信息
--
-- @treturn     t
-- @tfield[t]    integer    obj                 物品实例对象
-- @tfield[t]    integer    id                  物品ID
-- @tfield[t]    integer    sale_player_id      卖家Id
-- @tfield[t]    integer    res_ptr             物品资源指针
-- @tfield[t]    integer    total_price         总价
-- @tfield[t]    integer    num                 物品数量
-- @tfield[t]    integer    price               单价
-- @tfield[t]    integer    expire_time         到期时间
-- @usage
-- local info = exchange_ent.exchange_item_info()
-- print_r(info)
------------------------------------------------------------------------------------------------------------------------
function exchange.exchange_item_info(nType)
    nType = nType or 0
    local exchange_item_info = {}
    -- 0 搜索购买列表
    local list = exchange_unit.list(nType)
    -- xxmsg('list:'..#list)
    for i = 1, #list do
        local obj = list[i]
        if exchange_ctx:init(obj) then
            local up_time = math.floor(exchange_ctx:up_time() / 1000) + 1
            local down_time = math.floor(exchange_ctx:batch_collect_time() / 1000) + 1
            local result = {
                obj         = obj,
                id          = exchange_ctx:id(),
                total_price = exchange_ctx:total_price(),
                num         = exchange_ctx:num(),
                type        = exchange_ctx:type(),
                name        = exchange_ctx:name(),
                sale_price  = exchange_ctx:sale_price(),
                --status      = exchange_ctx:status(),
                up_time     = up_time,
                up_time2    = utils.convert_datetime(up_time),
                up_time3    = up_time > os.time(),
                down_time   = down_time,
                --down_time2  = utils.convert_datetime(down_time),
                down_time3  = os.time() > down_time,
            }
            result.price = result.total_price / result.num
            table.insert(exchange_item_info, result)
        end
    end
    --排序价格
    table.sort(exchange_item_info, function(a, b)
        return a.price < b.price
    end)

    return exchange_item_info
end

------------------------------------------------------------------------------------------------------------------------
-- 关闭购买窗口
------------------------------------------------------------------------------------------------------------------------
function this.close_buy_popup()
    local ret_b = false

    for i = 1, 10 do
        decider.sleep(1000)
        if not decider.is_working() then
            return false, "脚本终止,停止关闭交易行购买窗口"
        end
        if not exchange_unit.is_open_buy_popup() then
            ret_b = true
            break
        end
        trace.output('关闭购买窗口')
        exchange_unit.close_buy_popup()
    end
    return ret_b
end

------------------------------------------------------------------------------------------------------------------------
-- 执行购买指定ID 操作
------------------------------------------------------------------------------------------------------------------------
function this.buy_item(id, name)
    if id and exchange_unit.exchange_is_open() then
        -- 打开购买窗口
        if exchange_unit.exchange_is_open() then
            exchange_unit.set_buy_item(id)
            decider.sleep(2000)
        end
        -- 判断窗口是否打开
        if exchange_unit.is_open_buy_popup() then
            trace.output('购买：', name)
            decider.sleep(1000)
            -- 判断设置的购买ID是否正确     -- 这ID主要是在里面进行二次效验
            if exchange_unit.get_cur_set_item_id() == id then
                decider.sleep(1000)
                -- 窗口需打开
                if exchange_unit.exchange_is_open() then
                    -- TODO 再次检查下ID 是否被购买
                    -- 执行购买操作
                    exchange_unit.buy_item(id)
                end
            else
                -- 关闭购买窗
                this.close_buy_popup()
            end
        end
    end
end

------------------------------------------------------------------------------------
---[读取] 封装上架物品信息
---@return  table
------------------------------------------------------------------------------------
function exchange.get_exchange_sell_list_new()
    local list = exchange_unit.list(1)
    local result_list = {}
    for i = 1, #list do
        --xxmsg(111)
        local obj = list[i]
        if exchange_ctx:init(obj) then
            local up_time = math.floor(exchange_ctx:up_time() / 1000) + 1
            local down_time = math.floor(exchange_ctx:batch_collect_time() / 1000) + 1
            local branch = {
                name       = exchange_ctx:name(),
                id         = exchange_ctx:id(),
                num        = exchange_ctx:num(),
                sale_price = exchange_ctx:sale_price(),
                status     = exchange_ctx:status(),
                type       = exchange_ctx:type(),
                up_time    = up_time,                           -- 公示时间
                down_time  = down_time,                         -- 可以结算时间
                --down_time2 = utils.convert_datetime(down_time), -- 日期
                down_time3 = os.time() > down_time,             -- 是否能结算
                up_time2   = utils.convert_datetime(up_time),   -- 日期
                up_time3   = up_time < os.time(),               -- 布尔(是否可以查看到了)

            }
            --print_r(branch)
            table.insert(result_list, branch)
        end
    end

    return result_list
end

------------------------------------------------------------------------------------
-- 根据传入的id获取该物品在背包中达到数量，如果出售的数量大于等于背包中的数量，则退出
-- 否则判断出售的金额（单价*数量）是否小于10，小于10退出。
-- 倘若通过判断就进行相关界面窗口的打卡进行商品的上架
---[行为] 交易行上架物品
---@param   item_id  number  要上架的物品的id
---@param   item_price  number  要上架物品的单价
---@param   item_num  number  要上架物品的数量
---@param   item_name  string  要上架物品的名字
------------------------------------------------------------------------------------
function exchange.exchange_sell_by_info(item_id, item_price, item_num, item_name)
    -- 如果出售的数量大于等于背包中的数量，则退出
    -- 获取背包中该物品的数量

    local num = item.get_item_num_by_id(item_id)

    if item_num > num then
        return false, trace.output("出售的数量超出拥有该物品的数量")
    end
    -- 如果出售的金额（单价*数量）小于10则退出
    if item_price * item_num < 10 then
        return false, trace.output("出售的价格不能低于10钻")
    end
    -- 判断当前交易行系统页面是否打开，没有则打开
    for i = 1, 5 do
        if not exchange_unit.exchange_is_open() then
            -- 打开交易行系统
            exchange_unit.open_exchange()
            decider.sleep(1000)
        else
            break
        end
    end
    -- 判断是否在交易行系统页面,不是则不继续执行
    if not exchange_unit.exchange_is_open() then
        trace.log_info("打开交易行页面失败")
        return false, trace.output("打开交易行页面失败")
    end

    -- 判断当前交易行出售页面是否打开，没有则打开
    for i = 1, 5 do
        decider.sleep(1000)
        if exchange_unit.get_exchange_page() ~= 1 then
            -- 打开出售页面
            exchange_unit.change_exchange_page(1) -- 切换到出售
        else
            break
        end
    end
    -- 判断是否在出售页面,不是则不继续执行
    if exchange_unit.get_exchange_page() ~= 1 then
        trace.log_info("打开交易行出售页面失败")
        return false, trace.output("打开交易行出售页面失败")
    end
    -- 总价取整
    local price = math.floor(item_price * item_num)
    -- 如果在出售页面，打开出售弹框
    if exchange_unit.set_up_item(item_id, price, item_num) then
        decider.sleep(1000)
        -- 设置数量
        exchange_unit.set_sell_item_info(item_num, 0)
        decider.sleep(1000)
        -- 设置价格
        exchange_unit.set_sell_item_info(price, 1)
        decider.sleep(1000)
        trace.output("正在交易行上架（" .. item_name .. ")")
        -- 点击添加
        local ConfirmBtn = api.get_ui_id(
            '/Engine/Transient.GameEngine.MPlatformGameInstance.TradeMarketSellCalculatorPopupWidget_C.WidgetTree.ConfirmBtn',
            true)
        if ConfirmBtn ~= 0 then
            api.click_ui_btn(ConfirmBtn)
            decider.sleep(1000)

            local last_confirm = api.get_ui_id(
                '/Engine/Transient.GameEngine.MPlatformGameInstance.TradeMarketSellRegistrationPopupWidget_C.WidgetTree.ConfirmBtn',
                true)
            if last_confirm ~= 0 then
                api.click_ui_btn(last_confirm)
                decider.sleep(1000)
            end
        end
        return true
    else
        return false, trace.output("出售信息有误")
    end
end

------------------------------------------------------------------------------------------------------------------------
-- [行为] 物品下架
--
-- @tparam      integer     id              物品ID
-- @treturn     boolean
-- @usage
-- exchange_ent.down_item(物品ID)
------------------------------------------------------------------------------------------------------------------------
function this.down_item(id)
    -- 打开交易行窗口
    --exchange_ent.wc_open_exchange_widget()
    if exchange_unit.exchange_is_open() then
        --trace.output('物品下架')
        -- 自己出售列表
        local list = exchange_unit.list(1)
        local result = exchange_unit.down_item(id)
        for i = 1, 8 do
            decider.sleep(2000)
            if #list ~= #exchange_unit.list(1) then
                return true
            else
                return false, "下架异常 - 可能下架已出售的物品"
            end
            if not decider.is_working() then
                return false, '停止脚本运行'
            end
        end
        if not result then
            return false, '命令：exchange_unit.down_item(' .. id .. ') - 执行失败'
        end
        return false, '下架超时'
    end
    return false, '下架 - 交易窗未打开'
end

------------------------------------------------------------------------------------
-- [读取] 是否有可结算的物品
------------------------------------------------------------------------------------
function this.has_collect_item()

    local collect_list = exchange.exchange_item_info(1)
    local rst_b = false
    -- 保存可结算的物品表
    local can_collect_t = {}
    --local take_item_t = {}
    for _, collect_info in ipairs(collect_list) do
        if collect_info.down_time ~= 1 and ((os.time() - collect_info.down_time) > 0) then
            rst_b = true
            table.insert(can_collect_t, collect_info)
        end
    end
    return rst_b, can_collect_t
end

------------------------------------------------------------------------------------------------------------------------
-- [读取] 获取物品价格信息表
--
-- @tparam      integer     res_id              物品信息
-- @tparam      integer     level               物品等级
-- @treturn     t
-- @tfield[t]   integer     obj                 物品实例对象
-- @tfield[t]   integer     id                  物品ID
-- @tfield[t]   integer     sale_player_id      卖家Id
-- @tfield[t]   integer     res_ptr             物品资源指针
-- @tfield[t]   integer     total_price         总价
-- @tfield[t]   integer     num                 物品数量
-- @tfield[t]   integer     price               单价
-- @tfield[t]   integer     expire_time         到期时间
-- @usage
-- local info = exchange_ent.get_item_min_price(物品信息,物品等级)
-- print_r(info)
------------------------------------------------------------------------------------------------------------------------
function this.get_item_min_price(item_info, is_equip, level)
    level = level or 0
    local exchange_item_info = {}
    if exchange_unit.exchange_is_open() then
        local name = item_info
        if type(name) == 'table' then
            name = item_info.name
        end
        trace.output('查询【' .. name .. '】价格')
        decider.sleep(1000)
        local res_id = item_info and item_info.res_id or exchange_unit.get_item_res_id_byname(name)
        if not res_id or res_id == 0 then
            return false, trace.output("未能在交易行查询到该物品,请检查物品名")
        end
        if exchange_unit.get_exchange_page() == 0 then
            if is_equip and is_equip ~= 0 then
                --搜索物品
                exchange_unit.search_equip(res_id)
                --exchange_unit.search_item(res_id, level)
                decider.sleep(2000)
                --打开物品详情
                if exchange_unit.get_equip_num_by_resid(res_id, level) > 0 then
                    if exchange_unit.exchange_is_open() then
                        exchange_unit.search_item(res_id, level)
                        decider.sleep(2000)
                        exchange_item_info = exchange.exchange_item_info(0)
                    end
                end
                local num = exchange_unit.get_equip_num_by_resid(res_id, level)
                if num > 30 then
                    trace.output("翻页查询物品价格中")
                    -- 使用取模运算符 % 检查 num 是否能被 30 整除
                    local loop_count = num // 30
                    -- 如果不能整除（即余数不为 0），则加 1
                    if num % 30 ~= 0 then
                        loop_count = loop_count + 1
                    end
                    for i = 1, loop_count do
                        local success = exchange_unit.search_next_page(res_id, level)
                        trace.output("交易行翻页" .. i .. "次,共需" .. ((num // 30) + 1) .. "次")
                        if not decider.is_working() then
                            return false, "脚本终止"
                        end
                        if not success then
                            trace.output("查询物品价格完成")
                            break
                        end
                        decider.sleep(3000)
                    end
                    exchange_item_info = exchange.exchange_item_info(0)
                else
                    exchange_item_info = exchange.exchange_item_info(0)
                end
            else
                if exchange_unit.exchange_is_open() then
                    exchange_unit.search_item(res_id, 0)
                    trace.output("正在交易行搜索<" .. name .. ">")
                    local last_count = 0
                    for i = 1, 1000 do
                        if not decider.is_working() then
                            return false, "停止交易行搜索"
                        end
                        decider.sleep(2000)
                        local search_list = exchange_unit.list(0)
                        if #search_list < 30 then
                            break
                        end
                        if last_count == #search_list or (#search_list % 30 ~= 0) then
                            trace.output("翻页完成")
                            break
                        end
                        last_count = #search_list
                        -- TODO exchange_unit.search_next_page(res_id, level) 翻页总数为30的倍数时，可能需要判断对list取模判断
                        if exchange_unit.search_next_page(res_id, level) == false then
                            -- 内部校验断开
                            break
                        end
                    end
                    decider.sleep(2000)
                    -- 获取交易行可购买的物品列表
                    exchange_item_info = exchange.exchange_item_info(0)
                end
            end
        end
    else
        return false, {}
    end

    return true, exchange_item_info
end

------------------------------------------------------------------------------------------------------------------------
-- [读取] 获取物品价格信息表
--
-- @tparam      integer     res_id              物品信息
-- @tparam      integer     level               物品等级
-- @treturn     t
-- @tfield[t]   integer     obj                 物品实例对象
-- @tfield[t]   integer     id                  物品ID
-- @tfield[t]   integer     sale_player_id      卖家Id
-- @tfield[t]   integer     res_ptr             物品资源指针
-- @tfield[t]   integer     total_price         总价
-- @tfield[t]   integer     num                 物品数量
-- @tfield[t]   integer     price               单价
-- @tfield[t]   integer     expire_time         到期时间
-- @usage
-- local info = exchange_ent.get_item_min_price(物品信息,物品等级)
-- print_r(info)
------------------------------------------------------------------------------------------------------------------------
function this.get_item_min_price_ex(item_info, is_equip, level, is_found)
    local exchange_item_info = {}
    is_found = is_found or true
    local name = item_info
    if type(name) == 'table' then
        name = item_info.name
    end
    trace.output('查询【' .. name .. '】价格')
    decider.sleep(1000)
    local res_id = item_info and item_info.res_id or exchange_unit.get_item_res_id_byname(name)
    if not res_id or res_id == 0 then
        return false, trace.output("未能在交易行查询到该物品,请检查物品名")
    end
    level = level or 0
    if exchange_unit.get_exchange_page() == 0 then
        if is_equip and is_equip ~= 0 then
            --搜索物品
            if exchange_unit.exchange_is_open() then
                exchange_unit.search_equip(res_id)
                --exchange_unit.search_item(res_id, level)
                decider.sleep(2000)
            end
            --打开物品详情
            if exchange_unit.get_equip_num_by_resid(res_id, level) > 0 then
                if exchange_unit.exchange_is_open() then
                    exchange_unit.search_item(res_id, level)
                    decider.sleep(1500)
                    exchange_item_info = this.exchange_item_info()
                end
            end
            local num = exchange_unit.get_equip_num_by_resid(res_id, level)
            if num > 30 then
                trace.output("翻页查询物品价格中")
                -- 使用取模运算符 % 检查 num 是否能被 30 整除
                local loop_count = num // 30
                -- 如果不能整除（即余数不为 0），则加 1
                if num % 30 ~= 0 then
                    loop_count = loop_count + 1
                end
                for i = 1, loop_count do
                    local success = exchange_unit.search_next_page(res_id, level)
                    if not decider.is_working() then
                        return false, "脚本终止"
                    end
                    if not success then
                        trace.output("停止翻页")
                        break
                    end
                    decider.sleep(3000)
                    trace.output("交易行加载物品" .. i .. "次,共需" .. ((num // 30) + 1) .. "次")
                end
                exchange_item_info = this.exchange_item_info()
            else
                exchange_item_info = this.exchange_item_info()
            end
        else
            if is_found then
                if exchange_unit.exchange_is_open() then
                    exchange_unit.search_item(res_id, 0)
                    trace.output("正在交易行搜索<" .. name .. ">")
                    local last_count = 0
                    for i = 1, 1000 do
                        if not decider.is_working() then
                            return false, "停止交易行搜索"
                        end
                        decider.sleep(2000)
                        local search_list = exchange_unit.list(0)
                        if #search_list < 30 then
                            break
                        end
                        if last_count == #search_list or (#search_list % 30 ~= 0) then
                            trace.output("翻页完成")
                            break
                        end
                        last_count = #search_list
                        -- TODO exchange_unit.search_next_page(res_id, level) 翻页总数为30的倍数时，可能需要判断对list取模判断
                        if exchange_unit.search_next_page(res_id, 0) == false then
                            -- 内部校验断开
                            break
                        end
                    end
                    decider.sleep(2000)
                    -- 获取交易行可购买的物品列表
                    exchange_item_info = this.exchange_item_info()
                end
            else
                if exchange_unit.exchange_is_open() then
                    exchange_unit.search_item(res_id, 0)
                    trace.output("正在交易行搜索<" .. name .. ">")
                    local last_count = 0
                    for i = 1, 1000 do
                        if not decider.is_working() then
                            return false, "停止交易行搜索"
                        end
                        decider.sleep(2000)
                        local search_list = exchange_unit.list(0)
                        if #search_list < 30 then
                            break
                        end
                        if last_count == #search_list then
                            trace.output("翻页完成")
                            break
                        end
                        last_count = #search_list
                        -- TODO exchange_unit.search_next_page(res_id, level) 翻页总数为30的倍数时，可能需要判断对list取模判断
                        if exchange_unit.search_next_page(res_id, 0) == false then
                            -- 内部校验断开
                            break
                        end
                    end
                    decider.sleep(2000)
                    -- 获取交易行可购买的物品列表
                    exchange_item_info = this.exchange_item_info()
                end
            end
        end
    end

    return exchange_item_info
end

return this
